#include "networkclient.h"

NetworkClient::NetworkClient(QObject *parent) : QObject(parent) {
  connectAttemptCounter = 0;
}

void NetworkClient::configureNetwork(const QJsonObject &settings) {
  serverPort = settings["NetworkServerPort"].toDouble();
  serverIP = settings["NetworkServerIP"].toString();
  connectAttempts = settings["NetworkConnectAttempts"].toDouble();
  connectTimeout = settings["NetworkConnectTimeout"].toDouble();
}

void NetworkClient::connectToHost() {
  socket = new QTcpSocket(this);

  connect(socket, SIGNAL(connected()), this, SLOT(connected()));
  connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
  connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWritten(qint64)));
  connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
  connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(networkError(QAbstractSocket::SocketError)));


  socket->setSocketOption(QAbstractSocket::LowDelayOption,"1");
  socket->setSocketOption(QAbstractSocket::KeepAliveOption,"1");

  qDebug() << "Network: Connecting to" << serverIP << "on port" << serverPort;

  socket->connectToHost(serverIP,serverPort);

  if(!socket->waitForConnected(connectTimeout)) {
    qDebug() << "Network: Connect attempt failed" << socket->errorString() << socket->error();
    connectAttemptCounter++;

    if (socket->error() == QAbstractSocket::HostNotFoundError) {
      QTimer::singleShot(connectTimeout, this, SLOT(connectToHostTriggered()));
      qDebug() << "Timer single shot";
    }
    else
      if (connectAttemptCounter < connectAttempts) {
        qDebug() << "Network: Trying again";
        connectToHost();
      }
  }
}

void NetworkClient::connectToHostTriggered() {
  if (!isConnected())
    connectToHost();
}

void NetworkClient::disconnectFromHost() {
  socket->disconnectFromHost();

  qDebug() << "Network: Disconnected";
}

void NetworkClient::connected() {
  qDebug() << "Network: Connected";
  connectAttemptCounter = 0;
}

void NetworkClient::disconnected() {
  qDebug() << "Network: Disconnected from host";

  connectAttemptCounter = 0;
  connectToHost();
}

void NetworkClient::bytesWritten(qint64 bytes) {
  qDebug() << "Network: Bytes written" << bytes;
}

void NetworkClient::readyRead() {
  //Emit a signal that we have data to be read
  emit dataReady(socket->readAll());
}

bool NetworkClient::isConnected() {
  return(socket->isOpen());
}

void NetworkClient::networkError(QAbstractSocket::SocketError error) {
  emit socketError(error,socket->errorString());
}
